// This file is required by the index.html file and will
// be executed in the renderer process for that window.
// No Node.js APIs are available in this process because
// `nodeIntegration` is turned off. Use `preload.js` to
// selectively enable features needed in the rendering
// process.

const APP_VERSION = "v0.2";
const fs = require('fs');
const path = require('path')
const { remote, shell, ipcRenderer, ipcMain } = require('electron');
const { resolve } = require("dns")
const { electron } = require("process");
const { SSL_OP_SSLEAY_080_CLIENT_DH_BUG } = require('constants');
const resolvePath = require('./res/js/util').resolvePath;
const util = require('./res/js/util');
const icon_js = require('./res/js/icon');

const holder = document.getElementById("holder");
const btClose = document.getElementById("bt_close");
const btRebuildCachedIcon = document.getElementById("bt_rebuild_cached_icon");
const btCleanApps = document.getElementById("bt_clean_apps");

const tabs = $("#tabs");
var configData;
var tabsData;
var currentTabData;

function getMacOSInfoFilePath(path) {
    return path + '/Contents/info.plist';
}
function isMacOSApp(path) {
    if (path.length < 4) {
        return false;
    }
    if (!fs.existsSync(path)) {
        return false;
    }

    var stat = fs.statSync(path);

    if (!stat.isDirectory()) {
        return false;
    }
    if (path.substr(path.length - 4, 4).toLowerCase() == '.app') {
        return fs.existsSync(getMacOSInfoFilePath(path));
    }
}

function getMacOSAppInfo(appPath) {
    if (!isMacOSApp(appPath)) {
        return null;
    }

    var infoFile = getMacOSInfoFilePath(appPath);

    var info = {};
    var xmlData = fs.readFileSync(infoFile, { encoding: "utf-8" });

    info.bundleName = getValueOfPlist(xmlData, 'CFBundleName');
    info.bundleIconFile = getValueOfPlist(xmlData, 'CFBundleIconFile');
    info.bundleIdentifier = getValueOfPlist(xmlData, 'CFBundleIdentifier');

    console.log(info)
    if (!info.bundleName) {
        info.bundleName = path.basename(appPath);
    }
    if (!info.bundleIdentifier) {
        info.bundleIdentifier = "__mac_quick_start_" + info.bundleName;
    }
    return info;
}

function getAppIcon(appPath, appInfo) {
    if (appInfo) {
        //    get from icons
        var icon = icon_js.icons[appInfo.bundleIdentifier];
        if (!icon) {
            icon = icon_js.icons[appInfo.bundleName];
        }
        if (fs.existsSync(icon)) {
            return icon;
        }
        //    or get from res/icon/identifier
        icon = resolvePath('./res/icon/' + appInfo.bundleIdentifier + '.png');
        if (fs.existsSync(icon)) {
            return icon;
        }
        //    or get from res/icon/name
        icon = resolvePath('./res/icon/' + appInfo.bundleName + '.png');
        if (fs.existsSync(icon)) {
            return icon;
        }
    }

    if (appPath) {
        var appname = path.basename(appPath);
        var icon = icon_js.icons[appname]
        if (fs.existsSync(icon)) {
            return icon;
        }
        icon = resolvePath('./res/icon/' + appname + '.png');
        if (fs.existsSync(icon)) {
            return icon;
        }
    }

    if (appInfo) {
        var cachedIcon = icon_js.getCachedIconPath(appInfo.bundleIdentifier);
        if (fs.existsSync(cachedIcon)) {
            return cachedIcon;
        }
    }

    return icon_js.default_icon;
}

/** 
 * 不支持空值的情况
*/
function getValueOfPlist(xmlData, key) {
    var str_vtag = '<string>';
    var str_vetag = '</string>';
    var key_tag = '<key>' + key + '</key>';
    var key_index = xmlData.indexOf(key_tag);
    if (key_index < 0) {
        return null;
    }

    var value_index_begin = xmlData.indexOf(str_vtag, key_index + key_tag.length);
    if (value_index_begin < 0) {
        return null;
    }

    var value_index_end = xmlData.indexOf(str_vetag, value_index_begin + str_vtag.length);
    if (value_index_end < value_index_begin + str_vtag.length) {
        return null;
    }

    return xmlData.slice(value_index_begin + str_vtag.length, value_index_end);
}

holder.ondragenter = holder.ondragover = (event) => {
    event.preventDefault()
    holder.className = "jumbotron holder holder-ondrag"
}

holder.ondragleave = (event) => {
    event.preventDefault()
    holder.className = "jumbotron holder"
}

holder.ondrop = (event) => {
    event.preventDefault()
    holder.className = "jumbotron holder"
    if (event && event.dataTransfer && event.dataTransfer.files) {
        var fileList = event.dataTransfer.files;
        for (var i = 0; i < fileList.length; i++) {
            onReceiveFile(fileList[i]);
        }
    }
}

btClose.addEventListener('click', () => {
    ipcRenderer.sendSync('synchronous-message', { command: 'hide' });
});

btRebuildCachedIcon.addEventListener('click', () => {
    rebuildCachedIcons();
});

btCleanApps.addEventListener('click', ()=>{
    cleanApps();
});


function onReceiveFile(file) {
    if (!tabsData) {
        tabsData = [];
        configData.tabs = tabsData;
    }
    if (!currentTabData) {
        currentTabData = { name: "新建标签-1", id: "new_001", apps: [] };
        tabsData.push(currentTabData);
        appendTab(0);
        loadTab(0);
    }
    if (!currentTabData.apps) {
        currentTabData.apps = [];
    }
    currentTabData.apps.push({ path: file.path });
    appendItem({path:file.path}, true);

    util.saveConfig(configData);
}

function appendItem(appData, makeIconCache = false) {
    var appPath = util.getUserPath(appData.path);
    var name = appData.name;
    var icon = icon_js.resolveIcon(appData.icon);
    if (isMacOSApp(appPath)) {
        var info = getMacOSAppInfo(appPath);
        if (info && makeIconCache) {
            icon_js.makeCachedIcon(info.bundleIdentifier, appPath);
        }
        if(!icon){
            icon = getAppIcon(appPath, info);
        }
        if(!name){
            name = info.bundleName;
        }
        if (!name) {
            name = path.basename(appPath);
        }
    } else {
        if(!icon){
            icon = getAppIcon(appPath, null);
        }
        if(!name){
            name = path.basename(appPath);
        }
    }

    var $item = createItem(appPath, name, icon);
    $("#holder_container").append($item);
}

function createItem(appPath, name, icon) {
    var $item = $("<div class='card border-primary m-2 text-center' data-toggle='tooltip' data-placement='top' title='" + name + "' style='cursor: pointer; width:128px; height: 128px;'>");
    var $img = $("<img src='" + icon + "' class='card-img-top mt-1 mx-auto' style='width: 64px; height:64px;' />");
    var $text = $("<div class='card-body p-1 mt-2' style='border-top:1px dashed #d8d8d8;'><p class='card-text nav flex-column justify-content-center' style='height: 100%; font-size: 12px;'>" + name + "</p></div>");
    $item.append($img);
    $item.append($text);
    $item.click(function () {
        shell.openPath(appPath);
        if(configData.autohide){
            ipcRenderer.sendSync('synchronous-message', { command: 'hide' });
        }
    });
    return $item;
}

function appendTab(i) {
    if (!tabsData) {
        return;
    }
    if (i < 0 || i >= tabsData.length) {
        return;
    }

    var tab = tabsData[i];
    var $tab = $('<li class="nav-item" id="' + tab.id + '"><a class="nav-link" href="#" onclick="loadTab(' + i + ')" >' + tab.name + '</a></li>');
    if (i == 0) {
        currentTabData = tab;
    }
    tabs.append($tab);
}

function loadTab(i) {
    if (i < 0 || i >= tabsData.length) {
        return;
    }

    currentTabData = tabsData[i];
    loadTabByData(currentTabData);
}

function loadTabByData(tabData) {
    $('#tabs > li > a.active').removeClass('active');
    $('#' + tabData.id + '>a').addClass('active');
    $("#holder_container").empty();
    if (tabData && tabData.apps) {
        for (var k in tabData.apps) {
            var appData = tabData.apps[k];
            appendItem(appData);
        }
    }
}
/*
 * data structure
 * {
 *   version: "0.1",
 *   tabs: [
 *      {
 *          id: "001",
 *          name: "test",
 *          apps: [
 *                  {id:"a_001", name:"app name", path:"/path/of/app"}
 *                ]
 *      },
 *      {
 *          ...
 *      }
 *   ]
 * }
 *
 **/
function init() {
    reloadConfig();
    ipcRenderer.sendSync('synchronous-message', { command: 'regist_shortcut', key: configData.shortcut ? configData.shortcut : 'Command+Alt+V' });
}

function rebuildCachedIcons() {
    if (!tabsData) {
        return;
    }
    if (fs.existsSync(icon_js.cachedIconBasePath)) {
        util.delDir(icon_js.cachedIconBasePath);
    }
    fs.mkdirSync(icon_js.cachedIconBasePath);

    for (var i in tabsData) {
        for (var j in tabsData[i].apps) {
            var app = tabsData[i].apps[j];
            var appPath = app.path;
            if (isMacOSApp(appPath)) {
                var info = getMacOSAppInfo(appPath);
                if (info) {
                    icon_js.makeCachedIcon(info.bundleIdentifier, appPath);
                }
            }
        }
    }
    loadTabByData(currentTabData);
}

function cleanApps(){
    var _configData = util.readConfig();
    var _tabsData = _configData.tabs;
    if (!_tabsData) {
        return;
    }
    for (var i in _tabsData) {
        var newApps = [];
        for (var j in _tabsData[i].apps) {
            var app = _tabsData[i].apps[j];
            var appPath = app.path;
            if (fs.existsSync(util.getUserPath(appPath))) {
                newApps.push(app)
            }
        }
        _tabsData[i].apps = newApps;
    }
    util.saveConfig(_configData);

    tabs.empty();
    reloadConfig();
    loadTabByData(currentTabData);
}

function reloadConfig(){
    configData = util.readConfig();
    configData.version = APP_VERSION;
    util.saveConfig(configData);
    console.log("app version: " + configData.version);
    document.getElementById('app-version').innerText = configData.version;

    tabsData = configData.tabs;
    if (tabsData) {
        for (var i = 0; i < tabsData.length; i++) {
            appendTab(i);
        }
        loadTab(0);
    }
}

init();